﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace SPMS.Common
{
    /// <summary>
    /// 输入输出辅助类。
    /// </summary>
    public static class IOHelper
    {
        #region ---Public Method

        /// <summary>
        /// 将指定路径转换为绝对路径。
        /// </summary>
        /// <param name="path">相对路径。</param>
        /// <returns>转换出来的绝对路径。</returns>
        public static string MakePathRooted(string path)
        {
            //判断是否为空字符串
            if (string.IsNullOrEmpty(path))
            {
                //直接返回
                return path;
            }


            //判断路径是否为绝对路径
            if (!Path.IsPathRooted(path))
            {
                //判断是否指定为虚拟目录
                if (path.IndexOf('/') != -1)
                {
                    //映射路径
                    return HttpContext.Current.Server.MapPath(path);
                }
                else
                {
                    //使用应用程序根路径进行映射
                    return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
                }
            }
            else
            {
                //直接返回路径
                return path;
            }
        }

        /// <summary>
        /// 延迟删除指定的文件。
        /// </summary>
        /// <param name="filePath">要延迟删除的文件路径。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/12/10 15:55    创建
        /// </history>
        public static void DelayDeleteFile(string filePath)
        {
            //判断文件是否存在
            if (File.Exists(filePath))
            {
                //删除文件
                MoveFileEx(filePath, null, 4);
            }
        }

        /// <summary>
        /// 安全删除指定的文件。
        /// </summary>
        /// <param name="filePath">要删除的文件路径。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/12/10 15:55    创建
        /// </history>
        public static void DeleteFile(string filePath)
        {
            //判断文件是否存在
            if (File.Exists(filePath))
            {
                //设置文件属性
                File.SetAttributes(filePath, FileAttributes.Normal);

                //删除文件
                File.Delete(filePath);
            }
        }

        /// <summary>
        /// 安全删除指定的文件。
        /// </summary>
        /// <param name="filePath">要删除的文件路径。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/12/10 15:55    创建
        /// </history>
        public static void SafeDeleteFile(string filePath)
        {
            //判断文件是否存在
            if (File.Exists(filePath))
            {
                try
                {
                    //设置文件属性
                    File.SetAttributes(filePath, FileAttributes.Normal);

                    //删除文件
                    File.Delete(filePath);
                }
                catch
                {
                    //延迟删除文件
                    MoveFileEx(filePath, null, 4);
                }
            }
        }

        /// <summary>
        /// 安全删除指定的文件夹。
        /// </summary>
        /// <param name="folderPath">要删除的文件夹路径。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/12/10 15:55    创建
        /// </history>
        public static bool SafeDeleteFolder(string folderPath)
        {
            //判断文件是否存在
            if (File.Exists(folderPath))
            {
                try
                {
                    //删除文件夹
                    Directory.Delete(folderPath, true);

                    //返回删除成功
                    return true;
                }
                catch
                {
                    return false;
                }
            }

            //默认返回成功
            return true;
        }

        /// <summary>
        /// 从指定的文件名称中移除所有无效的文件名称字符。
        /// </summary>
        /// <param name="fileName">要移除无效文件名称字符的文件名称字符串。</param>
        /// <returns>移除无效文件名称字符的文件名称字符串。</returns>
        /// <remarks></remarks>
        /// <history>
        /// [ZaneZeng]               2011/6/3 10:06    创建
        /// </history>
        public static string TrimInvalidFileNameChars(string fileName)
        {
            //判断是否需要移除
            if (string.IsNullOrEmpty(fileName))
            {
                //不需要移除，则直接返回
                return fileName;
            }

            //替换路径分隔转义符
            fileName = fileName.Replace('\\', '_');

            //替换路径分隔转义符
            fileName = fileName.Replace('/', '_');

            //用于保存结果
            StringBuilder builder = new StringBuilder();

            //获得无效字符
            char[] invalidChars = Path.GetInvalidFileNameChars();

            //循环所有字符
            foreach (char candidate in fileName.ToCharArray())
            {
                //判断是否为无效字符
                if (Array.IndexOf<Char>(invalidChars, candidate) == -1)
                {
                    //如果不是无效字符，则添加
                    builder.Append(candidate);
                }
            }

            //返回结果
            return builder.ToString();
        }

        /// <summary>
        /// 准备文件路径。
        /// </summary>
        /// <param name="filePath">要准备的文件路径。</param>
        public static void PrepareFilePath(string filePath)
        {
            //判断是否为空字符串
            if (string.IsNullOrEmpty(filePath))
            {
                return;
            }

            //获得文件夹路径
            string path = Path.GetDirectoryName(filePath);

            //判断文件夹是否存在
            if (!Directory.Exists(path))
            {
                //创建文件夹
                Directory.CreateDirectory(path);
            }
        }

        /// <summary>
        /// 准备文件夹。
        /// </summary>
        /// <param name="filePath">要准备的文件夹路径。</param>
        public static void PrepareDirectory(string path)
        {
            //判断是否为空字符串
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            //判断文件夹是否存在
            if (!Directory.Exists(path))
            {
                //创建文件夹
                Directory.CreateDirectory(path);
            }
        }

        #endregion

        #region ---Import Method

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        private static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags);

        #endregion
    }
}
